package edu.univercidade.tcc.web;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.springframework.roo.addon.web.mvc.controller.RooWebScaffold;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import edu.univercidade.tcc.server.model.Issue;
import edu.univercidade.tcc.server.model.IssueStatus;
import edu.univercidade.tcc.server.model.Project;
import edu.univercidade.tcc.server.model.ProjectMember;

@RooWebScaffold(path = "issues", formBackingObject = Issue.class, delete = false)
@RequestMapping("/issues")
@Controller
public class IssueController {

	@RequestMapping(method = RequestMethod.POST)
	public String create(@Valid Issue issue, BindingResult bindingResult,
			Model uiModel, HttpServletRequest httpServletRequest) {
		if (bindingResult.hasErrors()) {
			uiModel.addAttribute("issue", issue);
			addDateTimeFormatPatterns(uiModel);
			return "issues/create";
		}
		uiModel.asMap().clear();
		issueService.saveIssue(issue, httpServletRequest.getUserPrincipal());
		issueService.sendMessage(issue, httpServletRequest.getUserPrincipal());
		return "redirect:/issues/"
				+ encodeUrlPathSegment(issue.getId().toString(),
						httpServletRequest);
	}

	@RequestMapping(method = RequestMethod.PUT)
	public String update(@Valid Issue issue, BindingResult bindingResult,
			Model uiModel, HttpServletRequest httpServletRequest) {
		if (bindingResult.hasErrors()) {
			uiModel.addAttribute("issue", issue);
			addDateTimeFormatPatterns(uiModel);
			return "issues/update";
		}
		uiModel.asMap().clear();
		issueService.updateIssue(issue);
		issueService.sendMessage(issue, httpServletRequest.getUserPrincipal());
		return "redirect:/issues/"
				+ encodeUrlPathSegment(issue.getId().toString(),
						httpServletRequest);
	}

	@RequestMapping(value = "/{id}", params = "form", method = RequestMethod.GET)
	public String updateForm(@PathVariable("id") Long id, Model uiModel,
			HttpServletRequest httpServletRequest) {
		Issue issue = issueService.findIssue(id);
		uiModel.addAttribute("issue", issue);
		uiModel.addAttribute("issuestatuses", issueStatusService
				.findValidIssueStatuses(issue,
						httpServletRequest.getUserPrincipal()));
		addDateTimeFormatPatterns(uiModel);
		return "issues/update";
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@RequestMapping(params = "form", method = RequestMethod.GET)
	public String createForm(Model uiModel) {
		uiModel.addAttribute("issue", new Issue());
		Set<IssueStatus> issueStatuses = new HashSet<IssueStatus>();
		issueStatuses.add(issueStatusService.findDefaultIssueStatus());
		uiModel.addAttribute("issuestatuses", issueStatuses);
		addDateTimeFormatPatterns(uiModel);
		List dependencies = new ArrayList();
		if (trackerService.countAllTrackers() == 0) {
			dependencies.add(new String[] { "tracker", "trackers" });
		}
		if (projectService.countAllProjects() == 0) {
			dependencies.add(new String[] { "project", "projects" });
		}
		if (projectMemberService.countAllProjectMembers() == 0) {
			dependencies
					.add(new String[] { "projectmember", "projectmembers" });
		}
		if (priorityService.countAllPrioritys() == 0) {
			dependencies.add(new String[] { "priority", "prioritys" });
		}
		if (projectMemberService.countAllProjectMembers() == 0) {
			dependencies
					.add(new String[] { "projectmember", "projectmembers" });
		}
		uiModel.addAttribute("dependencies", dependencies);
		return "issues/create";
	}

	@RequestMapping(params = { "find=ById", "form" }, method = RequestMethod.GET)
	public String findIssuesByIdForm(Model uiModel) {
		return "issues/findIssuesById";
	}

	@RequestMapping(params = "find=ById", method = RequestMethod.GET)
	public String findIssuesById(@RequestParam("id") Long id, Model uiModel) {
		uiModel.addAttribute("issues", Issue.findIssuesById(id).getResultList());
		return "issues/list";
	}

	@RequestMapping(params = { "find=ByProjectAndAssignedTo", "form" }, method = RequestMethod.GET)
	public String findIssuesByProjectAndAssignedToForm(Model uiModel) {
		uiModel.addAttribute("projects", Project.findAllProjects());
		uiModel.addAttribute("projectmembers",
				ProjectMember.findAllProjectMembers());
		return "issues/findIssuesByProjectAndAssignedTo";
	}

	@RequestMapping(params = "find=ByProjectAndAssignedTo", method = RequestMethod.GET)
	public String findIssuesByProjectAndAssignedTo(
			@RequestParam("project") Project project,
			@RequestParam("assignedTo") ProjectMember assignedTo, Model uiModel) {
		uiModel.addAttribute("issues",
				Issue.findIssuesByProjectAndAssignedTo(project, assignedTo)
						.getResultList());
		return "issues/list";
	}

	@RequestMapping(params = { "find=ByProjectAndAssignedToAndIssueStatus",
			"form" }, method = RequestMethod.GET)
	public String findIssuesByProjectAndAssignedToAndIssueStatusForm(
			Model uiModel, HttpServletRequest httpServletRequest) {
		List<Project> projects = new ArrayList<Project>();
		projects.add(new Project());
		projects.addAll(Project.findAllProjects());
		ProjectMember logged = projectMemberService
				.getUserByLogin(httpServletRequest.getUserPrincipal().getName());
		List<ProjectMember> projectmembers = new ArrayList<ProjectMember>();
		List<ProjectMember> allMembers = ProjectMember.findAllProjectMembers();
		allMembers.remove(logged);
		projectmembers.add(logged);
		projectmembers.add(new ProjectMember());
		projectmembers.addAll(allMembers);
		List<IssueStatus> issuestatuses = new ArrayList<IssueStatus>();
		issuestatuses.add(new IssueStatus());
		issuestatuses.addAll(IssueStatus.findAllIssueStatuses());
		uiModel.addAttribute("projects", projects);
		uiModel.addAttribute("projectmembers", projectmembers);
		uiModel.addAttribute("issuestatuses", issuestatuses);
		return "issues/findIssuesByProjectAndAssignedToAndIssueStatus";
	}

	@RequestMapping(params = "find=ByProjectAndAssignedToAndIssueStatus", method = RequestMethod.GET)
	public String findIssuesByProjectAndAssignedToAndIssueStatus(
			@RequestParam("project") Project project,
			@RequestParam("assignedTo") ProjectMember assignedTo,
			@RequestParam("issueStatus") IssueStatus issueStatus, Model uiModel) {
		uiModel.addAttribute("issues", issueService
				.findIssuesByProjectAndAssignedToAndIssueStatus(project,
						assignedTo, issueStatus));
		return "issues/list";
	}
}
